package xxl.robotlegs.extensions.localsignalmap.impl 
{
	import xxl.robotlegs.extensions.localsignalmap.api.ISignalMap;
	import xxl.signals.api.IMapSignal;
	import xxl.signals.api.ISignal;
	import xxl.signals.api.ISlot;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class SignalMap implements ISignalMap 
	{
		private var _suspended:Boolean = false;
		private const _listeners:Vector.<ISlot> = new Vector.<ISlot>;
		
		/* INTERFACE xxl.robotlegs.extensions.localsignalmap.api.ISignalMap */
		
		public function mapListener(signal:ISignal, listener:Function, once:Boolean = false):ISlot 
		{
			const currentListeners:Vector.<ISlot> = _listeners;
			const slot:ISlot = once
				? signal.addOnce(listener)
				: signal.add(listener);
			if (currentListeners.indexOf(slot) >= 0)
			{
				return slot;
			}
			currentListeners.push(slot);
			slot.enabled = !_suspended;
			return slot;
		}
		
		public function unmapListener(signal:ISignal, listener:Function):ISlot 
		{
			const currentListeners:Vector.<ISlot> = _listeners;
			const slot:ISlot = signal.remove(listener);
			if (slot)
			{
				const index:int = currentListeners.indexOf(slot);
				if (index >= 0)
				{
					currentListeners.splice(index, 1);
				}
			}
			return slot;
		}
		
		public function unmapListeners():void 
		{
			const currentListeners:Vector.<ISlot> = _listeners;
			for (var i:int = currentListeners.length; i--; )
			{
				currentListeners[i].remove();
			}
			currentListeners.length = 0;
		}
		
		public function suspend():void 
		{
			if (_suspended)
			{
				return;
			}
			_suspended = true;
			const currentListeners:Vector.<ISlot> = _listeners;
			for (var i:int = currentListeners.length; i--; )
			{
				currentListeners[i].enabled = false;
			}
		}
		
		public function resume():void 
		{
			if (!_suspended)
			{
				return;
			}
			_suspended = false;
			const currentListeners:Vector.<ISlot> = _listeners;
			for (var i:int = currentListeners.length; i--; )
			{
				currentListeners[i].enabled = true;
			}
		}
		
		public function mapListenerWithKey(signal:IMapSignal, key:Object, listener:Function, once:Boolean = false):ISlot 
		{
			const currentListeners:Vector.<ISlot> = _listeners;
			const slot:ISlot = once
				? signal.addOnceToMap(key, listener)
				: signal.addToMap(key, listener);
			if (currentListeners.indexOf(slot) >= 0)
			{
				return slot;
			}
			currentListeners.push(slot);
			slot.enabled = !_suspended;
			return slot;
		}
		
		public function unmapListenerWithKey(signal:IMapSignal, key:Object, listener:Function):ISlot 
		{
			const currentListeners:Vector.<ISlot> = _listeners;
			const slot:ISlot = signal.removeFromMap(key, listener);
			if (slot)
			{
				const index:int = currentListeners.indexOf(slot);
				if (index >= 0)
				{
					currentListeners.splice(index, 1);
				}
			}
			return slot;
		}
		
	}

}